using B.S.XZYData.Api.Wrter.Application.Command.Route;
using B.S.XZYData.Domain.LJC;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using Microsoft.Extensions.Logging;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Linq;
using System.Text;

namespace B.S.XZYData.Api.Wrter.Application.Handler.Route
{
    /// <summary>
    /// 导出工艺路线处理器
    /// </summary>
    public class ExportRouteHandler : IRequestHandler<ExportRouteCommand, ApiResult<byte[]>>
    {
        private readonly IBaseRepository<RouteModel> _routeRepository;
        private readonly IBaseRepository<RouteStepModel> _routeStepRepository;
        private readonly ILogger<ExportRouteHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        public ExportRouteHandler(
            IBaseRepository<RouteModel> routeRepository,
            IBaseRepository<RouteStepModel> routeStepRepository,
            ILogger<ExportRouteHandler> logger)
        {
            _routeRepository = routeRepository;
            _routeStepRepository = routeStepRepository;
            _logger = logger;
        }

        /// <summary>
        /// 处理导出工艺路线命令
        /// </summary>
        public async Task<ApiResult<byte[]>> Handle(ExportRouteCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 查询工艺路线数据
                var routes = _routeRepository.GetAll()
                    .WhereIF(!string.IsNullOrEmpty(request.RouteCode), x => x.Code.Contains(request.RouteCode))
                    .WhereIF(!string.IsNullOrEmpty(request.RouteName), x => x.Name.Contains(request.RouteName))
                    .ToList();

                if (!routes.Any())
                {
                    return new ApiResult<byte[]>
                    {
                        Code = ApiEnum.Fail,
                        Msg = "没有找到符合条件的工艺路线数据"
                    };
                }

                // 查询工艺路线步骤
                var routeIds = routes.Select(x => x.Id).ToList();
                var routeSteps = _routeStepRepository.GetAll()
                    .Where(x => routeIds.Contains(x.RouteId))
                    .ToList()
                    .OrderBy(x => x.RouteId)
                    .ThenBy(x => x.Sequence)
                    .ToList();

                // 创建工作簿
                IWorkbook workbook = new XSSFWorkbook();
                ISheet worksheet = workbook.CreateSheet("工艺路线");

                // 创建标题行样式
                ICellStyle headerStyle = workbook.CreateCellStyle();
                headerStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.LightBlue.Index;
                headerStyle.FillPattern = FillPattern.SolidForeground;
                headerStyle.BorderTop = BorderStyle.Thin;
                headerStyle.BorderBottom = BorderStyle.Thin;
                headerStyle.BorderLeft = BorderStyle.Thin;
                headerStyle.BorderRight = BorderStyle.Thin;

                IFont headerFont = workbook.CreateFont();
                headerFont.IsBold = true;
                headerStyle.SetFont(headerFont);

                // 创建数据行样式
                ICellStyle dataStyle = workbook.CreateCellStyle();
                dataStyle.BorderTop = BorderStyle.Thin;
                dataStyle.BorderBottom = BorderStyle.Thin;
                dataStyle.BorderLeft = BorderStyle.Thin;
                dataStyle.BorderRight = BorderStyle.Thin;

                // 设置表头
                var headers = new[]
                {
                    "路线编号", "路线名称", "备注", "工序编号", "工序名称", "序号", "标准工时", "工序备注"
                };

                // 创建标题行
                IRow headerRow = worksheet.CreateRow(0);
                for (int i = 0; i < headers.Length; i++)
                {
                    ICell cell = headerRow.CreateCell(i);
                    cell.SetCellValue(headers[i]);
                    cell.CellStyle = headerStyle;
                }

                // 填充数据
                int rowIndex = 1;
                foreach (var route in routes.OrderBy(x => x.Code))
                {
                    var steps = routeSteps.Where(x => x.RouteId == route.Id).ToList();
                    
                    if (steps.Any())
                    {
                        foreach (var step in steps)
                        {
                            IRow dataRow = worksheet.CreateRow(rowIndex);
                            
                            SetCellValue(dataRow, 0, route.Code ?? "", dataStyle);
                            SetCellValue(dataRow, 1, route.Name ?? "", dataStyle);
                            SetCellValue(dataRow, 2, route.Remark ?? "", dataStyle);
                            SetCellValue(dataRow, 3, step.ProcessCode ?? "", dataStyle);
                            SetCellValue(dataRow, 4, step.ProcessName ?? "", dataStyle);
                            SetCellValue(dataRow, 5, step.Sequence.ToString(), dataStyle);
                            SetCellValue(dataRow, 6, step.Ratio?.ToString() ?? "0", dataStyle);
                            SetCellValue(dataRow, 7, step.Type ?? "", dataStyle);

                            rowIndex++;
                        }
                    }
                    else
                    {
                        // 没有工序的路线也要显示
                        IRow dataRow = worksheet.CreateRow(rowIndex);
                        
                        SetCellValue(dataRow, 0, route.Code ?? "", dataStyle);
                        SetCellValue(dataRow, 1, route.Name ?? "", dataStyle);
                        SetCellValue(dataRow, 2, route.Remark ?? "", dataStyle);
                        SetCellValue(dataRow, 3, "", dataStyle);
                        SetCellValue(dataRow, 4, "", dataStyle);
                        SetCellValue(dataRow, 5, "", dataStyle);
                        SetCellValue(dataRow, 6, "", dataStyle);
                        SetCellValue(dataRow, 7, "", dataStyle);

                        rowIndex++;
                    }
                }

                // 自动调整列宽
                for (int i = 0; i < headers.Length; i++)
                {
                    worksheet.AutoSizeColumn(i);
                    // 设置最大列宽，防止过宽
                    if (worksheet.GetColumnWidth(i) > 8000)
                    {
                        worksheet.SetColumnWidth(i, 8000);
                    }
                }

                // 将工作簿写入内存流
                using var memoryStream = new MemoryStream();
                workbook.Write(memoryStream);
                var excelBytes = memoryStream.ToArray();

                _logger.LogInformation($"成功导出工艺路线 {routes.Count} 条，操作人：{request.OperateBy}");

                return new ApiResult<byte[]>
                {
                    Code = ApiEnum.Success,
                    Msg = $"成功导出 {routes.Count} 条工艺路线",
                    Data = excelBytes
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"导出工艺路线失败，操作人：{request.OperateBy}");
                return new ApiResult<byte[]>
                {
                    Code = ApiEnum.Fail,
                    Msg = $"导出失败：{ex.Message}"
                };
            }
        }

        /// <summary>
        /// 设置单元格值和样式的辅助方法
        /// </summary>
        private void SetCellValue(IRow row, int columnIndex, string value, ICellStyle style)
        {
            ICell cell = row.CreateCell(columnIndex);
            cell.SetCellValue(value);
            cell.CellStyle = style;
        }
    }
} 